package async;

import java.util.concurrent.CompletableFuture;
import com.ea.async.Async;

// java -jar ../lib/ea-async.jar async
// java -cp ../lib/ea-async.jar;. async.AsyncTest
// java -javaagent:../lib/ea-async.jar async.AsyncTest

// 240 ms, r = 4995000000
public class AsyncTest {
	private static final int N1 = 100;
	private static final int N2 = 100;
	private static final int N3 = 1000;
	private static final int N = N1 * N2 * N3;
	private static final AsyncFuture<Integer> af = new AsyncFuture<>();
	private static int s_i;

	private static CompletableFuture<Integer> f3() {
		for (int i = 0; i < N3; i++) {
			s_i = i;
			Async.await(af.yield());
		}
		return af;
	}

	private static CompletableFuture<Integer> f2() {
		for (int i = 0; i < N2; i++)
			Async.await(f3());
		return af;
	}

	@SuppressWarnings("UnusedReturnValue")
	private static CompletableFuture<Integer> f1() {
		for (int i = 0; i < N1; i++)
			Async.await(f2());
		return af;
	}

	public static void main(String[] args) {
		Async.init();
		long t = System.nanoTime();
		long r = 0;
		final Integer DUMMY = 0;
		f1();
		for (int i = 0; i < N; ++i) {
			r += s_i;
			af.complete(DUMMY);
		}
		System.out.println((System.nanoTime() - t) / 1_000_000 + " ms, r = " + r);
	}
}
